<!DOCTYPE html>
<html>
<!--
Copyright 2008 The Closure Library Authors. All Rights Reserved.

Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
-->
<!--
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Closure Unit Tests - goog.ui.ButtonRenderer</title>
  <script src="../base.js"></script>
  <script>
    goog.require('goog.dom.a11y');
    goog.require('goog.dom.a11y.Role');
    goog.require('goog.dom.a11y.State');
    goog.require('goog.dom.classes');
    goog.require('goog.style');
    goog.require('goog.testing.ExpectedFailures');
    goog.require('goog.testing.jsunit');
    goog.require('goog.testing.ui.rendererasserts');
    goog.require('goog.ui.Button');
    goog.require('goog.ui.ButtonRenderer');
    goog.require('goog.ui.ButtonSide');
  </script>
</head>
<body>
  <div id="sandbox"></div>
  <script>
    var button, buttonRenderer, testRenderer;
    var sandbox = goog.dom.getElement('sandbox');
    var expectedFailures = new goog.testing.ExpectedFailures();

    /**
     * A subclass of ButtonRenderer that overrides
     * {@code getStructuralCssClass} for testing purposes.
     * @constructor
     * @extends {goog.ui.ControlRenderer}
     */
    function TestRenderer() {
      goog.ui.ButtonRenderer.call(this);
    };
    goog.inherits(TestRenderer, goog.ui.ButtonRenderer);
    goog.addSingletonGetter(TestRenderer);

    /** {@override} */
    TestRenderer.prototype.getStructuralCssClass = function() {
      return 'goog-base';
    };

    function setUp() {
      buttonRenderer = goog.ui.ButtonRenderer.getInstance();
      button = new goog.ui.Button('Hello', buttonRenderer);
      testRenderer = TestRenderer.getInstance();
    }

    function tearDown() {
      button.dispose();
      goog.dom.removeChildren(sandbox);
      expectedFailures.handleTearDown();
    }

    function testConstructor() {
      assertNotNull('ButtonRenderer singleton instance must not be null',
          buttonRenderer);
    }

    function testGetAriaRole() {
      assertEquals('ButtonRenderer\'s ARIA role must have expected value',
          goog.dom.a11y.Role.BUTTON, buttonRenderer.getAriaRole());
    }

    function testCreateDom() {
      var element = buttonRenderer.createDom(button);
      assertNotNull('Element must not be null', element);
      assertEquals('Element must be a DIV', 'DIV', element.tagName);
      assertHTMLEquals('Element must have expected structure',
          '<div class="goog-button">Hello</div>',
          goog.dom.getOuterHtml(element));

      button.setTooltip('Hello, world!');
      button.setValue('foo');
      element = buttonRenderer.createDom(button);
      assertNotNull('Element must not be null', element);
      assertEquals('Element must be a DIV', 'DIV', element.tagName);
      assertSameElements('Element must have expected class name',
          ['goog-button'], goog.dom.classes.get(element));
      assertEquals('Element must have expected title', 'Hello, world!',
          element.title);
      assertUndefined('Element must have no value', element.value);
      assertEquals('Element must have expected contents', 'Hello',
          element.innerHTML);

      button.setSupportedState(goog.ui.Component.State.CHECKED, true);
      var element = buttonRenderer.createDom(button);
      assertEquals('button\'s aria-pressed attribute must be false', 'false',
          goog.dom.a11y.getState(element, goog.dom.a11y.State.PRESSED));
    }

    function testCreateDomAriaState() {
      button.setSupportedState(goog.ui.Component.State.CHECKED, true);
      button.setChecked(true);
      var element = buttonRenderer.createDom(button);

      assertEquals('button\'s aria-pressed attribute must be true', 'true',
          goog.dom.a11y.getState(element, goog.dom.a11y.State.PRESSED));
    }

    function testDecorate() {
      sandbox.innerHTML =
          '<div id="foo">Foo</div>\n' +
          '<div id="bar" title="Hello, world!">Bar</div>\n' +
          '<div id="toggle">Toggle</div>';

      var foo = new goog.ui.Button(null, buttonRenderer);
      foo.decorate(goog.dom.getElement('foo'));
      assertEquals('foo\'s tooltip must be the empty string', '',
          foo.getTooltip());
      foo.dispose();

      var bar = new goog.ui.Button(null, buttonRenderer);
      bar.decorate(goog.dom.getElement('bar'));
      assertEquals('bar\'s tooltip must be initialized', 'Hello, world!',
          bar.getTooltip());
      bar.dispose();

      var toggle = new goog.ui.Button(null, buttonRenderer);
      toggle.setSupportedState(goog.ui.Component.State.CHECKED, true);
      var element = goog.dom.getElement('toggle');
      toggle.decorate(element);
      assertEquals('toggle\'s aria-pressed attribute must be false', 'false',
          goog.dom.a11y.getState(element, goog.dom.a11y.State.PRESSED));
      toggle.dispose();
    }

    function testCollapse() {
      buttonRenderer.setCollapsed(button, goog.ui.ButtonSide.START);
      assertSameElements('Button should have class to collapse start',
          ['goog-button-collapse-left'], button.getExtraClassNames());
      buttonRenderer.setCollapsed(button, goog.ui.ButtonSide.END);
      assertSameElements('Button should have class to collapse end',
          ['goog-button-collapse-right'], button.getExtraClassNames());
      buttonRenderer.setCollapsed(button, goog.ui.ButtonSide.BOTH);
      assertSameElements('Button should have classes to collapse both',
          ['goog-button-collapse-left', 'goog-button-collapse-right'],
          button.getExtraClassNames());
    }

    function testCollapseRtl() {
      button.setRightToLeft(true);
      buttonRenderer.setCollapsed(button, goog.ui.ButtonSide.START);
      assertSameElements('Button should have class to collapse start',
          ['goog-button-collapse-right'], button.getExtraClassNames());
      buttonRenderer.setCollapsed(button, goog.ui.ButtonSide.END);
      assertSameElements('Button should have class to collapse end',
          ['goog-button-collapse-left'], button.getExtraClassNames());
      buttonRenderer.setCollapsed(button, goog.ui.ButtonSide.BOTH);
      assertSameElements('Button should have classes to collapse both',
          ['goog-button-collapse-left', 'goog-button-collapse-right'],
          button.getExtraClassNames());
    }

    function testCollapseWithStructuralClass() {
      testRenderer.setCollapsed(button, goog.ui.ButtonSide.BOTH);
      assertSameElements('Should use structural class for collapse classes',
          ['goog-base-collapse-left', 'goog-base-collapse-right'],
          button.getExtraClassNames());
    }

    function testUpdateAriaState() {
      var element = buttonRenderer.createDom(button);
      buttonRenderer.updateAriaState(element, goog.ui.Component.State.CHECKED,
          true);
      assertEquals('Button must have pressed ARIA state', 'true',
          goog.dom.a11y.getState(element, goog.dom.a11y.State.PRESSED));

      // Test for updating a state other than CHECKED
      buttonRenderer.updateAriaState(element, goog.ui.Component.State.DISABLED,
          true);
      assertEquals('Button must have disabled ARIA state', 'true',
          goog.dom.a11y.getState(element, goog.dom.a11y.State.DISABLED));

      buttonRenderer.updateAriaState(element, goog.ui.Component.State.CHECKED,
          false);
      assertEquals('Control must no longer have pressed ARIA state',
          'false',
          goog.dom.a11y.getState(element, goog.dom.a11y.State.PRESSED));
    }

    function testDoesntCallGetCssClassInConstructor() {
      goog.testing.ui.rendererasserts.
          assertNoGetCssClassCallsInConstructor(goog.ui.ButtonRenderer);
    }

  </script>
</body>
</html>
